<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>监视属性（侦听器）watch</title>
  <!-- 引入Vue -->
  <script src="../js/vue.js"></script>
</head>

<body>
  <!-- 当需要在数据变化时执行异步或开销较大的操作时，这个方式是最有用的 -->
  <!-- 准备容器 -->
  <div id="demo">
    <h2>今天天气很{{weather}}</h2>
    <button @click="changeWeather">切换天气</button>

    <h2>显示x={{num.x}},y={{num.y}}</h2>
    <button @click="num.x++;num.y++">修改数值</button>

    <h2>显示数组内容{{array}}</h2>
    <button @click="array[0].name='watch'">修改数组</button>
  </div>

  <script type='text/javascript'>
    Vue.config.productionTip = false; //设置为 false 以阻止 vue 在启动时生成生产提示。

    // 创建一个Vue实例
    const vm = new Vue({
      el: '#demo',
      data: {
        isHot: true,
        num: {
          x: 1,
          y: 2
        },
        array: [{ name: 'Vue' }]
      },

      methods: {
        changeWeather () {
          this.isHot = !this.isHot;
        }
      },

      computed: {
        weather () {
          return this.isHot ? '炎热' : '凉爽';
        }
      },
      //第一种方式
      watch: {
        //监视isHot
        /* isHot: {
          immediate: true, //默认值为false，改为true表示初始化时调用一次handler
          deep: true,  //深度监视,为了发现对象内部值的变化.注意监听数组的变更不需要这么做。
          //当监视的属性被修改时，调用handle
          handler (newVal, oldVal) {
            console.log('isHot被修改了', newVal, oldVal);
          }
        }, */
        //简写形式，当不需要immediate、deep配置项，之后handler回调函数时，可以简写
        isHot (newVal, oldVal) {
          console.log('isHot被修改了', newVal, oldVal);
        },

        /*         //监视num里面的x变化
                'num.x': {
                  handler (newVal, oldVal) {
                    console.log('num.x发生了变化', newVal, oldVal);
                  }
                },
                //监视num里面的任意值发生变化
                num: {
                  deep: true, //深度监视多层级数据，为了发现对象内部值的变化.注意监听数组的变更不需要这么做。
                  handler (newVal, oldVal) {
                    //因为num对象的地址值没有发生改变，所以newVal, oldVal指向同一个对象的地址
                    console.log('num发生了变化', newVal, oldVal);
                  }
                }, */

        /*         //监视array里面的任意值发生变化
                array: {
                  deep: true, //深度监视多层级数据，为了发现对象内部值的变化.注意监听数组的变更不需要这么做。
                  handler (newVal, oldVal) {
                    console.log('array发生了变化', newVal, oldVal);
                  }
                }*/
      },

    });

    //第二种方式，使用vm.$watch API
    // vm.$watch(expOrFn, callback, [options])
    // 参数：
    // { string | Function } expOrFn
    // { Function | Object } callback
    // { Object } [options]
    //    { boolean } deep
    //    { boolean } immediate
    // 返回值：{ Function } unwatch
    /*     vm.$watch('isHot', {
          immediate: true,
          deep: true,
          handler (newVal, oldVal) {
            console.log('isHot被修改了', newVal, oldVal);
          }
        }); */
    /*     //同样的，当不需要配置项，之后回到函数时，可以简写
        vm.$watch('isHot', function (newVal, oldVal) {
          console.log('isHot被修改了', newVal, oldVal);
        });
     */
  </script>

</body>

</html>